/**
 * Copyright 2011 Joao Miguel Pereira
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package eu.jpereira.trainings.designpatterns.structural.composite.model;

import java.util.ArrayList;
import java.util.List;


/**
 * @author Joao Pereira
 * 
 */
public abstract class CompositeShape extends Shape {

    List<Shape> shapes;

    public CompositeShape() {
            this.shapes = createShapesList();
    }
    //
    public CompositeShape asComposite()
    {
            return this;            
    }
    //
    /**
     * Remove a shape from this shape childrens
     *
     * @param shape
     *            the shape to remove
     * @return true if the shape was present and was removed, false if the shape
     *         was not present
     */
    public boolean removeShape(Shape shape) {
            // TODO: implement
            for( int i = 0; i < shapes.size(); i++)
            {
                    if(shapes.get(i) == shape)
                    {
                            shapes.remove(i);
                            return true;
                    }
            }
            return false; //*

    }

    /**
     * Return the total shapes count in case this is a composite
     *
     * @return the total count of shapes if the shape is composite. -1 otherwise
     */
    public int getShapeCount() {
            // TODO: implement
            if(shapes != null)
            {
                    return shapes.size();
            }
            else
            {
                    return 0; //*
            }
    }

    /**
     * Add a shape to this shape.
     *
     * @param shape
     *            The shape to add
     * @throws ShapeDoesNotSupportChildren
     *             if this shape is not a composite
     */
    public void addShape(Shape shape) throws ShapeDoesNotSupportChildren
    {
            // TODO: Implement
            shapes.add(shape);
            //
    }

    public List<Shape> getShapes() {
            // TODO: Implement
            return shapes;

    }

    /**
     * @param circle
     * @return
     */
    public List<Shape> getShapesByType(ShapeType circle) {
            //return null; //*
            // TODO: Implement
            List<Shape> typeList = new ArrayList<Shape>();
            for( int i = 0; i < shapes.size(); i++)
            {
                    if(shapes.get(i).getType() == circle)
                    {
                            typeList.add(shapes.get(i));
                    }
            }
            return typeList;
            //
    }

    /**
     * Return all shapes that are leafs in the tree
     *
     * @return
     */
    public List<Shape> getLeafShapes() {
            // TODO: Implement
            //return null; //*
            List<Shape> leafShapes = new ArrayList<Shape>();
            for( int i = 0; i < shapes.size(); i++)
            {
                    if(shapes.get(i).asComposite() == null)
                    {
                            leafShapes.add(shapes.get(i));
                    }
            }
            return leafShapes;
    }

    /**
     * Factory method for the list of children of this shape
     *
     * @return
     */
    protected List<Shape> createShapesList() {
            //return null; /*
            // TODO: Implement
            return new ArrayList<Shape>();
            //
    }
    public void move(int xIncrement, int yIncrement)
    {
            x += xIncrement;
            y += yIncrement;
            for(int i = 0; i < shapes.size(); i++)
            {
                    shapes.get(i).move(xIncrement, yIncrement);
            }
    }
}
